home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************
- * file: MENU.C
- * purpose:
- * menubar functions for simple gui
- * contains:
- * menu_open(MENU_ITEM menubar[],short number_of_items); draws a menubar
- * menu_message_handler(MESSAGE *message,MENU_ITEM *menu); handles menu messages
- * menu_close(MENU_ITEM menubar[]); erases a menubar
- * menu_modify(MENU_ITEM menubar[],short menu_id,unsigned short status); modifies the status of a menu item, ACTIVE, GRAY or HIDDEN
- * menu_clear(MENU_ITEM menubar[]); clear any open popups
- * popup_open(POPUP_ITEM popup[],short number_of_items); draws a popup
- * popup_message_handler(MESSAGE *message,POPUP_ITEM *popup); handles popup messages
- * popup_close(POPUP_ITEM popup[]); erases a popup
- * popup_modify(POPUP_ITEM popup[],short popup_id,unsigned short status); modifies the status of a popup item, ACTIVE, GRAY or HIDDEN
- * system: Written for the flash graphics library in Zortech 3.0
- * copyright: 1991 by David Weber. All rights reserved.
- * This software can be used for any purpose as object, library or executable.
- * It cannot be sold for profit as source code.
- * history:
- * 12-22-91 - initial code
- * 01-31-93 - this code is now obsolete, see the CPP gui package
- **************************************************************/
-
- #include <stdio.h>
- #include <string.h>
- #include "gui.h"
-
- /* local data */
- static MENU_ITEM *menu_item_is_selected = NULL;
- static MENU_ITEM *menu_last_seen = NULL;
-
- /* local prototypes */
- static void selection_focus(short x1,short y1,short x2,short y2);
- static void selection_unfocus(short x1,short y1,short x2,short y2);
- static short menu_draw_text(short x,short y,char *str,unsigned short status);
- static short menu_clear_any_items(MENU_ITEM *menu);
- static void menu_select_item(MENU_ITEM *menu);
- static void menu_clear_item(MENU_ITEM *menu);
- static void menu_select_previous_item(MENU_ITEM *first,MENU_ITEM *current);
- static void menu_select_next_item(MENU_ITEM *first,MENU_ITEM *current);
- static void menu_default_message_handler(MESSAGE *message);
- static MENU_ITEM *menu_current(MENU_ITEM *first);
- static void menu_modify_draw(MENU_ITEM *menu);
- static short popup_from_menu(MENU_ITEM *first,MENU_ITEM *active);
- static void popup_clear_any_item(POPUP_ITEM *popup);
- static void popup_select_item(POPUP_ITEM *popup);
- static void popup_clear_item(POPUP_ITEM *popup);
- static void popup_select_previous_item(POPUP_ITEM *first,POPUP_ITEM *current);
- static void popup_select_next_item(POPUP_ITEM *first,POPUP_ITEM *current);
- static POPUP_ITEM *popup_current(POPUP_ITEM *first);
- static void popup_modify_draw(POPUP_ITEM *popup);
-
-
-
- /************************************************
- * function: short menu_open(MENU_ITEM menubar[],short number_of_items)
- * register a menubar, initialize the hotspots and draw it
- * parameters: array of menu items in menu and number of items to expect
- * returns: 1 opened or 0 if failed cuz of lack of resources or bad data
- ************************************************/
- short menu_open(MENU_ITEM menubar[],short number_of_items)
- {
- fg_box_t menu_area;
- short i,j,text_x,text_y,cell_height;
- MENU_ITEM *m,*m2;
- POPUP_ITEM *p;
- MESSAGE error;
-
- i = 0; /* verify parameters */
- if (number_of_items < 0 || number_of_items > MENU_MAX_ITEMS)
- i = 1;
- else
- for (j = 0 ; j < number_of_items ; j++)
- {
- m = &menubar[j];
- if (m->name == NULL || (m->status & ~MENU_BITS) ||
- m->accelerator < KEY_MIN || m->accelerator > KEY_MAX ||
- m->number_of_popup_items < 0 || m->number_of_popup_items > POPUP_MAX_ITEMS)
- i = 1;
- }
- if (i)
- {
- error.id = gui_errno = M_INVALID_PARMS;
- error.data.ptr_data = menu_open;
- message_send(&error);
- return 0;
- }
- fg_msm_hidecursor();
- cell_height = gui_char_height + 6;
- text_y = 3;
- if (gui_char_height + gui_char_height/2 > cell_height)
- {
- cell_height = gui_char_height + gui_char_height/2;
- text_y = gui_char_height/4;
- }
- menu_area[FG_X1] = fg.displaybox[FG_X1]; /* coordinates of menubar */
- menu_area[FG_X2] = fg.displaybox[FG_X2];
- menu_area[FG_Y1] = fg.displaybox[FG_Y2] - cell_height;
- menu_area[FG_Y2] = fg.displaybox[FG_Y2];
- fg_boxclip(fg.displaybox,menu_area,menu_area);
- if (!object_add(OBJECT_MENU,(GENERIC_MESSAGE_HANDLER)menu_message_handler,menubar,menu_area))
- { /* add object to active list */
- fg_msm_showcursor();
- fg_flush();
- return 0;
- }
- fg_fillbox(COLOR_MENU_BACKGROUND,FG_MODE_SET,~0,menu_area); /* draw bar */
- fg_drawbox(COLOR_MENU_FOREGROUND,FG_MODE_SET,~0,FG_LINE_SOLID,menu_area,fg.displaybox);
- text_x = fg.displaybox[FG_X1] + 2 * gui_char_width;
- text_y += menu_area[FG_Y1];
- for (i = 0, m2 = NULL ; i < number_of_items ; i++)
- {
- m = &menubar[i];
- m->screen[FG_X1] = text_x-2*gui_char_width; /* locate hotspots */
- m->screen[FG_Y1] = menu_area[FG_Y1];
- m->screen[FG_Y2] = menu_area[FG_Y2];
- text_x = menu_draw_text(text_x,text_y,m->name,m->status); /* draw text */
- m->screen[FG_X2] = text_x + 2 * gui_char_width;
- text_x += 4 * gui_char_width;
- if (m->popup != NULL)
- { /* link popup items */
- for (j = 0, p = m->popup ; j < m->number_of_popup_items-1 ; j++, p++)
- p->next = p + 1;
- p->next = NULL;
- }
- m->next = NULL; /* link menu items */
- if (m2 != NULL)
- m2->next = m;
- m2 = m;
- }
- fg_msm_showcursor();
- fg_flush();
- return 1;
- }
-
-
- /************************************************
- * function: void menu_message_handler(MESSAGE *message,MENU_ITEM *menu)
- * handles messages for menu objects
- * parameters: pointer to message, pointer to object data
- * returns: nothing
- ************************************************/
- void menu_message_handler(MESSAGE *message,MENU_ITEM *menu)
- {
- MENU_ITEM *m;
- POPUP_ITEM *p;
- short key,x,y;
-
- menu_item_is_selected = NULL;
- switch (message->id)
- {
- case M_KEY:
- key = message->data.short_data.x;
- input_handler_set_default(menu_default_message_handler);
- menu_last_seen = menu;
- for (m = menu ; m != NULL ; m = m->next)
- {
- if (m->status & MENU_SELECTED)
- { /* if menu item selected */
- menu_item_is_selected = m; /* found a selected item */
- if (key == RETURN && m->popup == NULL)
- { /* select current item */
- message->id = m->id;
- return;
- }
- if (key == LEFTARROW)
- { /* select previous item */
- menu_select_previous_item(menu,m);
- message->id = M_NONE;
- return;
- }
- if (key == RIGHTARROW)
- { /* select next menu item */
- menu_select_next_item(menu,m);
- message->id = M_NONE;
- return;
- }
- if (key == SHIFTTAB)
- { /* select previous popup or menu */
- if (m->popup == NULL || popup_current(m->popup) == m->popup)
- {
- menu_select_previous_item(menu,m);
- m = menu_current(menu);
- }
- message->data.short_data.x = UPARROW;
- message_send_object(message,(void *) m->popup);
- message->id = M_NONE;
- return;
- }
- if (key == TAB)
- { /* select next popup or menu item */
- if (m->popup == NULL || popup_current(m->popup)->next == NULL)
- menu_select_next_item(menu,m);
- else
- {
- message->data.short_data.x = DOWNARROW;
- message_send_object(message,(void *) m->popup);
- }
- message->id = M_NONE;
- return;
- }
- }
- if (m->status & MENU_ACTIVE && m->accelerator == key)
- { /* found an accelerator key */
- if (m->popup != NULL)
- popup_from_menu(menu,m);
- else
- {
- menu_clear_any_items(menu);
- menu_select_item(m);
- }
- message->id = m->id;
- return;
- }
- if (m->popup != NULL)
- { /* check accelerators on popup attached to menubar item */
- for (p = m->popup ; p != NULL ; p = p->next)
- if (p->status & MENU_ACTIVE && p->accelerator == key)
- {
- if ((m->status & MENU_SELECTED) == 0)
- popup_from_menu(menu,m);
- if ((p->status & MENU_SELECTED) == 0)
- {
- popup_clear_any_item(m->popup);
- popup_select_item(p);
- }
- message->id = p->id;
- return;
- }
- }
- }
- break;
- case M_MOUSE_LEFT:
- case M_MOUSE_CENTER:
- case M_MOUSE_RIGHT:
- x = message->data.short_data.x;
- y = message->data.short_data.y;
- for (m = menu ; m != NULL ; m = m->next)
- {
- if (m->status & MENU_SELECTED)
- {
- input_handler_set_default(menu_default_message_handler);
- menu_item_is_selected = m; /* found a selected item */
- }
- if (fg_pt_inbox(m->screen,x,y))
- { /* menu item selected */
- if (m->status & MENU_ACTIVE)
- {
- if (m->popup != NULL)
- popup_from_menu(menu,m);
- else
- {
- menu_clear_any_items(menu);
- menu_select_item(m);
- }
- message->id = m->id;
- return;
- }
- message->id = M_NONE;
- return;
- }
- }
- break;
- default:
- return;
- }
- }
-
-
- /************************************************
- * function: short menu_close(MENU_ITEM menubar[])
- * parameters: pointer to previously opened menubar
- * returns: 1 if closed or 0 if failed
- ************************************************/
- short menu_close(MENU_ITEM menubar[])
- {
- short ret;
- MENU_ITEM *m;
-
- fg_msm_hidecursor();
- if ((ret = object_remove(menubar)) != 0)
- for (m = menubar ; m != NULL ; m = m->next)
- m->status &= ~MENU_SELECTED;
- fg_msm_showcursor();
- fg_flush();
- return ret;
- }
-
-
- /************************************************
- * function: short menu_modify(MENU_ITEM menubar[],short menu_id,unsigned short status)
- * set the status of an element in a previously opened menubar or associated
- * popup and redraw it
- * This will set only MENU_ACTIVE, MENU_GRAY or MENU_HIDDEN
- * parameters: menu array, id of menu or popup element to set, new status value
- * returns: 1 if set or 0 if not opened or improper id
- ************************************************/
- short menu_modify(MENU_ITEM menubar[],short menu_id,unsigned short status)
- {
- MENU_ITEM *m;
- POPUP_ITEM *p;
-
- if (object_exists(menubar) == NULL)
- return 0;
- for (m = menubar ; m != NULL ; m = m->next)
- {
- if (m->id == menu_id) /* check menu */
- {
- m->status = (m->status & ~MENU_STATUS_MASK) | (status & MENU_STATUS_MASK);
- menu_modify_draw(m);
- if (m->status & MENU_SELECTED)
- if ((m->status & MENU_ACTIVE) == 0)
- menu_select_next_item(menubar,m);
- return 1;
- }
- for (p = m->popup ; p != NULL ; p = p->next) /* check attached popups */
- if (p->id == menu_id)
- {
- p->status = (p->status & ~MENU_STATUS_MASK) | (status & MENU_STATUS_MASK);
- popup_modify_draw(p);
- if (p->status & MENU_SELECTED)
- if ((p->status & MENU_ACTIVE) == 0)
- popup_select_next_item(m->popup,p);
- return 1;
- }
- }
- return 0;
- }
-
-
- /************************************************
- * function: short menu_clear(MENU_ITEM menubar[])
- * parameters: pointer to previously opened menubar
- * returns: 1 if cleared or 0 if failed
- ************************************************/
- short menu_clear(MENU_ITEM menubar[])
- {
- if (object_exists(menubar) == NULL)
- return 0;
- menu_clear_any_items(menubar);
- return 1;
- }
-
-
- /************************************************
- * function: short popup_open(POPUP_ITEM popup[],short number_of_items,short x,short y)
- * register a popup, initialize the hotspots and draw it
- * parameters: array of popup items in popup, number of items to expect and screen location
- * returns: 1 opened or 0 if failed cuz of lack of resources
- ************************************************/
- short popup_open(POPUP_ITEM popup[],short number_of_items,short x,short y)
- {
- fg_box_t popup_area;
- short i,j,text_y,right_x,cell_height;
- POPUP_ITEM *p,*p2;
- MESSAGE error;
-
- i = 0; /* verify parameters */
- if (number_of_items < 0 || number_of_items > POPUP_MAX_ITEMS)
- i = 1;
- else
- for (j = 0 ; j < number_of_items ; j++)
- {
- p = &popup[j];
- if (p->name == NULL || (p->status & ~MENU_BITS) ||
- p->accelerator < KEY_MIN || p->accelerator > KEY_MAX)
- i = 1;
- }
- if (i)
- {
- error.id = gui_errno = M_INVALID_PARMS;
- error.data.ptr_data = menu_open;
- message_send(&error);
- return 0;
- }
- fg_msm_hidecursor();
- cell_height = gui_char_height + 6;
- popup_area[FG_X1] = x; /* coordinates of popup */
- popup_area[FG_Y1] = y - number_of_items * cell_height;
- popup_area[FG_X2] = x;
- popup_area[FG_Y2] = y;
- for (i = 0 ; i < number_of_items ; i++)
- { /* maximum string width */
- right_x = x + (strlen(popup[i].name)+2) * gui_char_width;
- if (right_x > popup_area[FG_X2])
- popup_area[FG_X2] = right_x;
- }
- fg_boxclip(fg.displaybox,popup_area,popup_area);
- if (!object_add(OBJECT_POPUP,(GENERIC_MESSAGE_HANDLER)popup_message_handler,popup,popup_area))
- { /* add to active object list */
- fg_msm_showcursor();
- fg_flush();
- return 0;
- }
- fg_fillbox(COLOR_MENU_BACKGROUND,FG_MODE_SET,~0,popup_area); /* draw popup */
- fg_drawbox(COLOR_MENU_FOREGROUND,FG_MODE_SET,~0,FG_LINE_SOLID,popup_area,fg.displaybox);
- text_y = y + (cell_height-gui_char_height)/2;
- for (i = 0, p2 = NULL ; i < number_of_items ; i++)
- {
- p = &popup[i];
- p->screen[FG_X1] = x; /* locate hotspots */
- p->screen[FG_X2] = right_x;
- p->screen[FG_Y2] = y;
- text_y -= cell_height;
- y -= cell_height;
- p->screen[FG_Y1] = y;
- (void) menu_draw_text(x+gui_char_width,text_y,p->name,p->status); /* draw text */
- p->next = NULL; /* link popups */
- if (p2 != NULL)
- p2->next = p;
- p2 = p;
- }
- fg_msm_showcursor();
- fg_flush();
- return 1;
- }
-
-
- /************************************************
- * function: void popup_message_handler(MESSAGE *message,POPUP_ITEM *popup)
- * handles messages for popup objects
- * parameters: pointer to message, pointer to object data
- * returns: nothing
- ************************************************/
- void popup_message_handler(MESSAGE *message,POPUP_ITEM *popup)
- {
- POPUP_ITEM *p;
- short key,x,y;
-
- switch (message->id)
- {
- case M_KEY:
- key = message->data.short_data.x;
- for (p = popup ; p != NULL ; p = p->next)
- {
- if (p->status & MENU_SELECTED) /* if popup is open and selected */
- {
- if (key == DOWNARROW) /* move to next item */
- {
- popup_select_next_item(popup,p);
- message->id = M_NONE;
- return;
- }
- if (key == UPARROW) /* move to previous item */
- {
- popup_select_previous_item(popup,p);
- message->id = M_NONE;
- return;
- }
- if (key == RETURN) /* current item selected */
- {
- message->id = p->id;
- return;
- }
- }
- if (p->status & MENU_ACTIVE && p->accelerator == key)
- {
- popup_clear_any_item(popup);
- popup_select_item(p);
- message->id = p->id; /* accelerator key selected */
- return;
- }
- }
- break;
- case M_MOUSE_LEFT:
- case M_MOUSE_CENTER:
- case M_MOUSE_RIGHT:
- x = message->data.short_data.x;
- y = message->data.short_data.y;
- for (p = popup ; p != NULL ; p = p->next)
- if (fg_pt_inbox(p->screen,x,y))
- { /* mouse clicked on item in an open popup */
- if (p->status & MENU_ACTIVE)
- {
- popup_clear_any_item(popup);
- popup_select_item(p);
- message->id = p->id;
- return;
- }
- message->id = M_NONE;
- return;
- }
- break;
- default:
- return;
- }
- }
-
-
- /************************************************
- * function: short popup_close(POPUP_ITEM popup[])
- * parameters: pointer to previously opened popup
- * returns: 1 if closed or 0 if failed
- ************************************************/
- short popup_close(POPUP_ITEM popup[])
- {
- short ret;
- POPUP_ITEM *p;
-
- fg_msm_hidecursor();
- if ((ret = object_remove(popup)) != 0)
- for (p = popup ; p != NULL ; p = p->next)
- p->status &= ~MENU_SELECTED;
- fg_msm_showcursor();
- fg_flush();
- return ret;
- }
-
-
- /************************************************
- * function: short popup_modify(POPUP_ITEM popup[],short popup_id,unsigned short status)
- * set the status of an element in a previously opened popup and redraw it
- * This will set only MENU_ACTIVE, MENU_GRAY or MENU_HIDDEN
- * parameters: popup array, id of element to set, new status value
- * returns: 1 if set or 0 if not opened or improper id
- ************************************************/
- short popup_modify(POPUP_ITEM popup[],short popup_id,unsigned short status)
- {
- POPUP_ITEM *p;
-
- if (object_exists(popup) == NULL)
- return 0;
- for (p = popup ; p != NULL ; p = p->next)
- if (p->id == popup_id)
- {
- p->status = (p->status & ~MENU_STATUS_MASK) | (status & MENU_STATUS_MASK);
- popup_modify_draw(p);
- if (p->status & MENU_SELECTED)
- if ((p->status & MENU_ACTIVE) == 0)
- popup_select_next_item(popup,p);
- return 1;
- }
- return 0;
- }
-
-
- /* ---------------- LOCAL FUNCTIONS ---------------- */
-
- /* highlight a menu/popup selection */
- static void selection_focus(short x1,short y1,short x2,short y2)
- {
- fg_box_t selection;
-
- fg_msm_hidecursor();
- fg_make_box(selection,x1,y1,x2,y2);
- fg_drawbox(COLOR_MENU_FOCUS,FG_MODE_SET,~0,FG_LINE_SOLID,selection,fg.displaybox);
- selection[FG_X1]++;
- selection[FG_Y1]++;
- selection[FG_X2]--;
- selection[FG_Y2]--;
- fg_drawbox(COLOR_MENU_FOCUS,FG_MODE_SET,~0,FG_LINE_SOLID,selection,fg.displaybox);
- fg_msm_showcursor();
- fg_flush();
- }
-
-
- /* clear a menu/popup selection */
- static void selection_unfocus(short x1,short y1,short x2,short y2)
- {
- fg_box_t selection;
-
- fg_msm_hidecursor();
- fg_make_box(selection,x1,y1,x2,y2);
- fg_drawbox(COLOR_MENU_BACKGROUND,FG_MODE_SET,~0,FG_LINE_SOLID,selection,fg.displaybox);
- selection[FG_X1]++;
- selection[FG_Y1]++;
- selection[FG_X2]--;
- selection[FG_Y2]--;
- fg_drawbox(COLOR_MENU_BACKGROUND,FG_MODE_SET,~0,FG_LINE_SOLID,selection,fg.displaybox);
- fg_msm_showcursor();
- fg_flush();
- }
-
-
- /* ---------------- MENUS ---------------- */
-
- /* close any open popups in menu and clear selected items, return 1 if OK or 0 if fail */
- static short menu_clear_any_items(MENU_ITEM *menu)
- {
- MENU_ITEM *m;
-
- for (m = menu ; m != NULL ; m = m->next)
- if (m->status & MENU_SELECTED)
- {
- menu_clear_item(m);
- if(m->popup != NULL)
- {
- if (!popup_close(m->popup))
- return 0;
- }
- }
- return 1;
- }
-
-
- /* highlight a menu item and mark status as selected */
- static void menu_select_item(MENU_ITEM *menu)
- {
- selection_focus(menu->screen[FG_X1]+gui_char_width,menu->screen[FG_Y1]+1,menu->screen[FG_X2]-gui_char_width,menu->screen[FG_Y2]-1);
- menu->status |= MENU_SELECTED;
- }
-
-
- /* clear a menu item's highlights and status flag */
- static void menu_clear_item(MENU_ITEM *menu)
- {
- selection_unfocus(menu->screen[FG_X1]+gui_char_width,menu->screen[FG_Y1]+1,menu->screen[FG_X2]-gui_char_width,menu->screen[FG_Y2]-1);
- menu->status &= ~MENU_SELECTED;
- }
-
-
- /* move to previous menu item */
- static void menu_select_previous_item(MENU_ITEM *first,MENU_ITEM *current)
- {
- MENU_ITEM *m,*mark;
-
- mark = current;
- do
- {
- for (m = first ; m->next != current && m->next != NULL ; m = m->next)
- ;
- current = m;
- if (current == mark)
- break;
- } while ((current->status & MENU_ACTIVE) == 0);
- if (current->popup != NULL)
- popup_from_menu(first,current);
- else
- {
- menu_clear_any_items(first);
- menu_select_item(current);
- }
- }
-
-
- /* move to next menu item */
- static void menu_select_next_item(MENU_ITEM *first,MENU_ITEM *current)
- {
- MENU_ITEM *mark;
-
- mark = current;
- do
- {
- if (current->next == NULL)
- current = first;
- else
- current = current->next;
- if (current == mark)
- break;
- } while ((current->status & MENU_ACTIVE) == 0);
- if (current->popup != NULL)
- popup_from_menu(first,current);
- else
- {
- menu_clear_any_items(first);
- menu_select_item(current);
- }
- }
-
-
- /* draw menu text str at coordinates x,y using ACTIVE,GRAY HIDDEN status, return new x value */
- static short menu_draw_text(short x,short y,char *str,unsigned short status)
- {
- short i,color;
-
- for (i = 0 ; str[i] != 0 ; i++)
- {
- if (status & MENU_GRAY)
- color = COLOR_MENU_GRAY;
- else if (status & MENU_HIDDEN)
- color = COLOR_MENU_BACKGROUND;
- else
- color = COLOR_MENU_FOREGROUND;
- if (str[i] == '&')
- {
- i++;
- if (str[i] == 0)
- i--;
- if (str[i] != '&' && color == COLOR_MENU_FOREGROUND)
- color = COLOR_MENU_HIGHLIGHT;
- }
- fg_putc(color,FG_MODE_SET,~0,FG_ROT0,x,y,str[i],fg.displaybox);
- x += gui_char_width;
- }
- return x;
- }
-
-
- /* closes any popups left open when a click occurs somewhere */
- static void menu_default_message_handler(MESSAGE *message)
- {
- short key;
-
- if (menu_item_is_selected != NULL) /* close any open menu items */
- {
- menu_clear_any_items(menu_item_is_selected);
- message->id = M_NONE;
- }
- else if (message->id == M_KEY)
- {
- key = message->data.short_data.x;
- if (key == TAB || key == SHIFTTAB || key == DOWNARROW || key == UPARROW || key == RIGHTARROW || key == LEFTARROW || key == RETURN)
- { /* nothing open, so open first item */
- if (menu_last_seen->popup != NULL)
- popup_from_menu(menu_last_seen,menu_last_seen);
- else
- {
- menu_clear_any_items(menu_last_seen);
- menu_select_item(menu_last_seen);
- }
- message->id = M_NONE;
- }
- }
- }
-
-
- /* return a pointer to the currently selected menu item or NULL if none */
- static MENU_ITEM *menu_current(MENU_ITEM *first)
- {
- MENU_ITEM *m;
-
- for (m = first ; m != NULL ; m = m->next)
- if (m->status & MENU_SELECTED)
- return m;
- return NULL;
- }
-
-
- /* redraw a modified menu item */
- static void menu_modify_draw(MENU_ITEM *menu)
- {
- short text_y;
- fg_box_t text_area;
-
- fg_msm_hidecursor();
- text_y = 3;
- if (gui_char_height + gui_char_height/2 > gui_char_height + 6)
- text_y = gui_char_height/4;
- fg_box_cpy(text_area,menu->screen);
- text_area[FG_X1] += 2*gui_char_width;
- text_area[FG_Y1] += text_y;
- text_area[FG_X2] -= 2*gui_char_width;
- text_area[FG_Y2] = text_area[FG_Y1] + gui_char_height - 1;
- fg_fillbox(COLOR_MENU_BACKGROUND,FG_MODE_SET,~0,text_area);
- menu_draw_text(text_area[FG_X1],text_area[FG_Y1],menu->name,menu->status);
- fg_msm_showcursor();
- fg_flush();
- }
-
-
- /* ---------------- POPUPS ---------------- */
-
- /* close any open popups and open this popup */
- static short popup_from_menu(MENU_ITEM *first,MENU_ITEM *active)
- {
- short x,dx;
- POPUP_ITEM *p;
-
- if (active->popup == NULL || active->number_of_popup_items <= 0)
- return 0;
- if (!menu_clear_any_items(first))
- return 0;
- for (p = active->popup, dx = 0 ; p != NULL ; p = p->next) /* find width of popup */
- {
- x = (strlen(p->name)+2) * gui_char_width;
- if (x > dx)
- dx = x;
- }
- x = active->screen[FG_X1]+gui_char_width;
- if (x + dx > fg.displaybox[FG_X2]) /* fit within menubar */
- x = fg.displaybox[FG_X2] - dx;
- if (x < fg.displaybox[FG_X1])
- x = fg.displaybox[FG_X1];
- if (!popup_open(active->popup,active->number_of_popup_items,x,active->screen[FG_Y1]))
- return 0;
- menu_select_item(active);
- if (active->popup->status & MENU_ACTIVE)
- popup_select_item(active->popup);
- else
- popup_select_next_item(active->popup,active->popup);
- return 1;
- }
-
-
- /* highlight a popup item and mark status as selected */
- static void popup_select_item(POPUP_ITEM *popup)
- {
- selection_focus(popup->screen[FG_X1]+1,popup->screen[FG_Y1]+1,popup->screen[FG_X2]-1,popup->screen[FG_Y2]-1);
- popup->status |= MENU_SELECTED;
- }
-
-
- /* clear all selected popup items */
- static void popup_clear_any_item(POPUP_ITEM *popup)
- {
- POPUP_ITEM *p;
-
- for (p = popup ; p != NULL ; p = p->next)
- if (p->status & MENU_SELECTED)
- popup_clear_item(p);
- }
-
-
- /* clear a popup item's highlights and status flag */
- static void popup_clear_item(POPUP_ITEM *popup)
- {
- selection_unfocus(popup->screen[FG_X1]+1,popup->screen[FG_Y1]+1,popup->screen[FG_X2]-1,popup->screen[FG_Y2]-1);
- popup->status &= ~MENU_SELECTED;
- }
-
-
- /* move to previous popup item */
- static void popup_select_previous_item(POPUP_ITEM *first,POPUP_ITEM *current)
- {
- POPUP_ITEM *p,*mark;
-
- mark = current;
- do
- {
- for (p = first ; p->next != current && p->next != NULL ; p = p->next)
- ;
- current = p;
- if (current == mark)
- break;
- } while ((current->status & MENU_ACTIVE) == 0);
- popup_clear_item(mark);
- popup_select_item(current);
- }
-
-
- /* move to next popup item */
- static void popup_select_next_item(POPUP_ITEM *first,POPUP_ITEM *current)
- {
- POPUP_ITEM *mark;
-
- mark = current;
- do
- {
- if (current->next == NULL)
- current = first;
- else
- current = current->next;
- if (current == mark)
- break;
- } while ((current->status & MENU_ACTIVE) == 0);
- popup_clear_item(mark);
- popup_select_item(current);
- }
-
-
- /* return a pointer to the currently selected popup item or NULL if none */
- static POPUP_ITEM *popup_current(POPUP_ITEM *first)
- {
- POPUP_ITEM *p;
-
- for (p = first ; p != NULL ; p = p->next)
- if (p->status & MENU_SELECTED)
- return p;
- return NULL;
- }
-
-
- /* redraw a modified popup item */
- static void popup_modify_draw(POPUP_ITEM *popup)
- {
- fg_box_t text_area;
-
- fg_msm_hidecursor();
- fg_box_cpy(text_area,popup->screen);
- text_area[FG_X1] += gui_char_width;
- text_area[FG_Y1] += 3;
- text_area[FG_X2] -= gui_char_width;
- text_area[FG_Y2] = text_area[FG_Y1] + gui_char_height - 1;
- fg_fillbox(COLOR_MENU_BACKGROUND,FG_MODE_SET,~0,text_area);
- menu_draw_text(text_area[FG_X1],text_area[FG_Y1],popup->name,popup->status);
- fg_msm_showcursor();
- fg_flush();
- }